import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadLocalRandom;

public class PharseTest2 {
    // 1.通过phaser台同步的线程成为party(参与者) 所有需要同步的party必须有同一个phaser对象 party
    // 需要想phaser注册，执行phaser.regiseter()方法注册，该方法仅仅时增加phaser中的线程计数，
    // 也可以通过构造器注册，比如 new Phaser(3)
    // 2.unarrivedparty达到一个phaser(阶段)之前处于unarrived状态
    // 3.arrived 到达时处于arrived状态，一个arrived的party也被称为arrival
    // 4.deregister 一个线程可以在 arrive某个phase后退出（deregister）与参与这中途退赛相同，可以使用‘arriveAndDeregister()
    // 方法是心啊（到达并注销）
    // 5.phase计数 初始阶段为0 ，当一个阶段的所有线程arrive时，会将phase计数加1这个动作成为advice
    // 在advance时，会触发onAdvance(int phase,int registeredParties) 方法的执行
    // 6.onAdvance(int phase,int registeredParties)
    // 可以在这个方法中定义advance过程中需要执行何种操作
    // 如果需要进入下一阶段（phase） 执行，返回false 如果返回true,会导致phaser结束,该方法时终止phaser的关键
    public static void main(String[] args) throws InterruptedException {
        Phaser pharse = new Phaser();
        for (int i = 0; i < 4; i++) {
            pharse.register();
            new Thread(new Runner(pharse,i)).start();
        }
    }

    static class Runner extends Thread {
        private Phaser phaser;
        private int no;
        public Runner(Phaser phaser,int no) {
            this.phaser = phaser;
            this.no = no;
        }


        @Override
        public void run() {
            try {
                System.out.println(this.getName() + "is Ready");
                phaser.arriveAndAwaitAdvance();
                System.out.println(this.getName() + " runnung...");
                if(no == 1){
                    phaser.arriveAndDeregister();
                    return;
                }
                System.out.println(this.getName() + "is ready2");
                if(no == 3){
                    phaser.arriveAndDeregister();
                    return;
                }

                phaser.arriveAndAwaitAdvance();
                System.out.println(this.getName() + " runnung...");
                Thread.sleep(ThreadLocalRandom.current().nextInt(3000));
                System.out.println(this.getName() + "is Ready3");
                phaser.arriveAndAwaitAdvance();
                System.out.println(this.getName() + " over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
